/* "qDroid v.2009.08.27 alfa-3"
 * qdl_TcpSocket.h
 *
 *  Created on: 18.05.2009
 *      Author: Denjs
 *
 *
 * !!!!  QT += network 
 */

#ifndef TCP_SOCKET_H_
#define TCP_SOCKET_H_

#include <QtCore>
#include <QtScript>
#include <QtNetwork> 
#include "classes/bots/qdl_TcpServer.h"

/*:: [[@TcpSocket]] 
[[:QDroid_classes]] 

**TcpSocket** - класс предоставляющий функциональность для работы с tcp-соединением. \n 
В общем случае , это может быть и клиентское соединение, но сейчас это
серверное соединение, возвращаемое классом [[TcpServer]] при подключении клиента.

См также: 
  * [[TcpServer]], 
  * [[tcplink_otpd]] (сходный по задачам класс из набора транспортных модулей проекта [[OTPD]]) 

Общие характеристики:
  * имя конструктора QtScript: TcpSocket
  * C++ имя класса : qdl_TcpSocket , наследован от QObject
  * Является оболочкой вокруг класса QTcpSocket
  * Являетля классом расширения. имя расширения : [[qdlib_tcpserver]]
  * Требует для нормальной работы загруженного расширения : [[qdlib_bytearray]] 


*/

class qdl_TcpSocket :public QObject //yes, this is not good. But I do not see any other way to get  TcpSocket from QTcpServer...
{
    Q_OBJECT

public:
	qdl_TcpSocket(QTcpSocket *_tcpConnection=0);
	virtual ~qdl_TcpSocket();

    	//это (ниже) нужно что бы можно было засунуть класс в контейнер QList
    	// возможно так-же связано с работой QtScript движка - см функции
		// после определения класса
		//
    	// спец. настройки для QtScript (v 2008.11.25)
    	// Шаг 1 из 8
    	qdl_TcpSocket(const qdl_TcpSocket &other);

    	//это (ниже) нужно что бы можно было засунуть t_FileList в контейнер QList
    	// возможно так-же связано с работой QtScript движка - см функции
    	// после определения класса
    	//
    	// спец. настройки для QtScript (v 2008.11.25)
    	// Шаг 2 из 8
    	qdl_TcpSocket& operator=(const qdl_TcpSocket &other);


    	// спец. настройки для QtScript (v 2008.11.25)
    	// Шаг 2.2 из 8
		bool operator==(const qdl_TcpSocket &other ) const;
//======================================================
//2144
//public: //оболочки от абстрактного сокета
public slots:

	void abort ();
	qint64 bytesAvailable () const;
	qint64 bytesToWrite () const;
	bool canReadLine () const;
	void close ();
	//void connectToHost ( const QString & hostName, quint16 port, OpenMode openMode = ReadWrite );
	  void connectToHost ( const QString & hostName, quint16 port);
//n\a	//void connectToHost ( const QHostAddress & address, quint16 port, OpenMode openMode = ReadWrite )
	void disconnectFromHost ();
	//SocketError error () const; //see errorString
	bool flush ();
	bool isValid () const;
	//QHostAddress localAddress () const
	  QString localAddress () const;
	quint16 localPort () const;
	//QHostAddress peerAddress () const
	 QString peerAddress () const;
	QString peerName () const;
	quint16 peerPort () const;
//n\a	//QNetworkProxy proxy () const
	qint64 readBufferSize () const;
//n\a	//void setProxy ( const QNetworkProxy & networkProxy )
	void setReadBufferSize ( qint64 size );
//	//bool setSocketDescriptor ( int socketDescriptor, SocketState socketState = ConnectedState, OpenMode openMode = ReadWrite )
	int socketDescriptor () const;
//	//SocketType socketType () const
	//SocketState state () const
	  int state () const;
	bool waitForConnected ( int msecs = 30000 );
 	bool waitForDisconnected ( int msecs = 30000 );

//32 public functions inherited from QIODevice
	qint64 write ( const QByteArray & byteArray );//write
	QByteArray readLine ( qint64 maxSize = 0 );//readline
	QString errorString () const;
	//virtual 
	 bool waitForReadyRead ( int msecs = 30000 );
	 QByteArray readAll();
	/*
	virtual bool atEnd () const
	virtual qint64 bytesAvailable () const
	virtual qint64 bytesToWrite () const
	virtual bool canReadLine () const
	virtual void close ()
	//QString errorString () const
	bool getChar ( char * c )
	bool isOpen () const
	bool isReadable () const
	virtual bool isSequential () const
	bool isTextModeEnabled () const
	bool isWritable () const
	virtual bool open ( OpenMode mode )
	OpenMode openMode () const
	qint64 peek ( char * data, qint64 maxSize )
	QByteArray peek ( qint64 maxSize )
	virtual qint64 pos () const
	bool putChar ( char c )
	qint64 read ( char * data, qint64 maxSize )
	QByteArray read ( qint64 maxSize )
	
	qint64 readLine ( char * data, qint64 maxSize )
	QByteArray readLine ( qint64 maxSize = 0 )
	virtual bool reset ()
	virtual bool seek ( qint64 pos )
	void setTextModeEnabled ( bool enabled )
	virtual qint64 size () const
	void ungetChar ( char c )
	virtual bool waitForBytesWritten ( int msecs )
	virtual bool waitForReadyRead ( int msecs )
	qint64 write ( const char * data, qint64 maxSize )
	qint64 write ( const QByteArray & byteArray )
	*/

//29 public functions inherited from QObject  - it does not needs to be Inherited  -we ere qobject-inherited already
	


signals:
	void connected();
	void disconnected();
//	void error ( QAbstractSocket::SocketError socketError );
	void hostFound ();
//	//void proxyAuthenticationRequired ( const QNetworkProxy & proxy, QAuthenticator * authenticator )
//n\a	//void stateChanged ( QAbstractSocket::SocketState socketState )
//4 signals inherited from QIODevice
	void readyRead();
//1 signal inherited from QObject 


protected:
	//void setLocalAddress ( const QHostAddress & address )
//	void setLocalPort ( quint16 port );
	//void setPeerAddress ( const QHostAddress & address )
//	void setPeerName ( const QString & name );
//	void setPeerPort ( quint16 port );
	//void setSocketError ( SocketError socketError )
	//void setSocketState ( SocketState state )

//======================================================
	void connectit();//моя функция подключить внутренний объект к оболочке
	
public slots:
	QString GetId();
	
 
 
protected:
	QTcpSocket *tcpConnection;
	
};

//----------------------------------------------------------------------
//нужно чтобы можно было передавать эти элементы как параметры в функции внутри QtScript
// спец. настройки для QtScript (v 2008.11.25)
// Шаг 3 из 8
Q_DECLARE_METATYPE(qdl_TcpSocket*);

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 4 из 8

static QScriptValue f_qdroid_qdl_TcpSocket_toScriptValue(QScriptEngine *engine, qdl_TcpSocket* const &in)
{ return engine->newQObject(in); }

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 5 из 8

static void f_qdroid_qdl_TcpSocket_fromScriptValue(const QScriptValue &object, qdl_TcpSocket* &out)
{ out = qobject_cast<qdl_TcpSocket*>(object.toQObject()); }

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 6 из 8
//конструктор для последующего его определения как new в скрипте
static QScriptValue f_qdroid_qdl_TcpSocket_constructor(QScriptContext *QSContext, QScriptEngine *QSEngine)
	{
		//t_BaseBot BaseBot;
		QScriptValue QtSObject;
		QtSObject=QSEngine->newQObject(new qdl_TcpSocket()); //
		return QtSObject;
	}

// шаги 7 и 8 должны быть выполнены в программе которая собирается использовать данный класс совместно со скриптовым движком
//// спец. настройки для QtScript (v 2008.11.25)
//// Шаг 7 из 8
//// - это qScriptRegisterMetaType регистрация но это нужно сделать в головном классе
//// например в глобальной функции "define__qdroid_qtscript_functions()"
////// t_FileList TYPE defenition
//	qScriptRegisterMetaType(_QSEngine, f_qdroid_qdl_TcpSocket_toScriptValue, f_qdroid_qdl_TcpSocket_fromScriptValue);

//// спец. настройки для QtScript (v 2008.11.25)
//// Шаг 8 из 8
////- определение конструктора в контексте скрипта
////// t_FileList NEW constructor defenition
//	QScriptValue fun5_constr = _QSEngine->newFunction(f_qdroid_qdl_TcpSocket_constructor);
//	_QSEngine->globalObject().setProperty("qdl_TcpSocket", fun5_constr);

static int f_qdroid_qdl_TcpSocket_register(QScriptEngine *_QSEngine)
	{
		//шаг 7 регистрация метатипа
		qScriptRegisterMetaType(_QSEngine, f_qdroid_qdl_TcpSocket_toScriptValue, f_qdroid_qdl_TcpSocket_fromScriptValue);
		//шаг 8 регистрация конструктора
		_QSEngine->globalObject().setProperty("TcpSocket", _QSEngine->newFunction(f_qdroid_qdl_TcpSocket_constructor));
		return 0;
	}
//----------------------------------------------------------------------

#endif /* TCP_SOCKET_H_ */
